﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using Deployment.BuildManager.Common;

namespace Deployment.BuildManager.UI
{
    public partial class BuildManagerForm : Form
    {
        #region ATTRIBUTES

        private bool _formIsValid = true;
        private string[] m_arrItemToolTips;
        private Thread buildThread = null;
        private delegate void SetMessageReceivedCallback(object sender, Deployment.BuildManager.ExternalProcess.Common.MessageEventArgs e);
        #endregion

        #region CONSTRUCTORS

        public BuildManagerForm()
        {
            InitializeComponent();
            btnCancelar.Visible = false;
        }

        #endregion

        #region EVENTS

        private void btnCancelar_Click(object sender, EventArgs e)
        {
            if (buildThread != null)
            {
                if (buildThread.IsAlive)
                {
                    buildThread.Abort("Empacotamento Cancelado.");
                    ConfigScreen(true);
                }
            }
        }

        private void btnEmpacotar_Click(object sender, EventArgs e)
        {
            _formIsValid = true;
            if (this.ValidateForm())
            {
                btnCancelar.Visible = true;
                StartProgressBar();

                try
                {
                    this.buildThread = new Thread(new ParameterizedThreadStart((o) => { this.Execute(this.cmbProdutos.SelectedItem.ToString(), this.txtUriBranch.Text, this.txtUriSetup.Text, 
                                                    this.txtModulo.Text, this.txtVersao.Text, this.txtLocalPath.Text, this.txtNomePacote.Text, 
                                                    lstDescricao.Items.Cast<String>().ToList()); }));
                    this.buildThread.Start();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void btnFechar_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void btnAdicionar_Click(object sender, EventArgs e)
        {
            if (txtDescricao.Text.Trim().Length > 0)
            {
                lstDescricao.Items.Add(txtDescricao.Text);
                txtDescricao.Text = "";
                txtDescricao.Focus();

                Array.Resize(ref m_arrItemToolTips, lstDescricao.Items.Count);
                lstDescricao.Items.CopyTo(m_arrItemToolTips, 0);
            }
        }

        private void lstDescricao_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue.Equals(46))
                lstDescricao.Items.Remove(lstDescricao.SelectedItem);
        }

        private void lstDescricao_MouseMove(object sender, MouseEventArgs e)
        {
            if (lstDescricao.Items.Count > 0)
            {
                try
                {
                    ListBox objListBox = (ListBox)sender;
                    int itemIndex = -1;
                    if (m_arrItemToolTips != null)
                    {
                        if (objListBox.ItemHeight != 0)
                        {
                            itemIndex = e.Y / objListBox.ItemHeight;
                            itemIndex += objListBox.TopIndex;
                        }
                        if ((itemIndex >= 0) && (itemIndex < m_arrItemToolTips.Length))
                        {
                            listToolTip.SetToolTip(objListBox, m_arrItemToolTips[itemIndex]);
                        }
                        else
                            listToolTip.Hide(objListBox);
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }

        private void btnLimpar_Click(object sender, EventArgs e)
        {
            ClearForm(this.Controls);
        }

        private void btnLocalizar_Click(object sender, EventArgs e)
        {
            if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                this.txtLocalPath.Text = this.folderBrowserDialog1.SelectedPath;
            }
        }

        #endregion

        #region METHODS

        private void ClearForm(Control.ControlCollection controlCollection)
        {
            foreach (Control ctrl in controlCollection)
            {
                if (ctrl.Controls.Count > 0)
                {
                    ClearForm(ctrl.Controls);
                }

                if (ctrl is TextBox)
                {
                    (ctrl as TextBox).Clear();
                }
                else if (ctrl is ListBox)
                {
                    (ctrl as ListBox).Items.Clear();
                }
                else if (ctrl is ComboBox)
                {
                    (ctrl as ComboBox).SelectedIndex = -1;
                }
            }
        }

        private bool ValidateForm()
        {
            //if (this.cmbProdutos.SelectedIndex > -1 && this.cmbProdutos.SelectedItem.ToString().Equals("Sinacor", StringComparison.OrdinalIgnoreCase))
            //{
            //    ValidateField(this.txtModulo, "Informe o Acrônimo do Módulo.");
            //}
            ValidateField(this.txtUriBranch, "Informe a URI do Branch de Hotfix ou Service Pack.");
            ValidateField(this.txtUriSetup, "Informe a URI do Projeto de Setup.");
            ValidateField(this.txtVersao, "Informe a versão do HTX/SPK.");
            ValidateField(this.txtNomePacote, "Informe o nome do pacote.");
            ValidateField(this.cmbProdutos, "Informe o produto.");
            return _formIsValid;
        }

        private void ConfigScreen(bool value)
        {
            this.txtUriBranch.Enabled = value;
            this.txtUriSetup.Enabled = value;
            this.txtModulo.Enabled = value;
            this.btnAdicionar.Enabled = value;
            this.btnEmpacotar.Enabled = value;
            this.txtDescricao.Enabled = value;
            this.lstDescricao.Enabled = value;
            this.txtLocalPath.Enabled = value;
            this.txtVersao.Enabled = value;
            this.btnLocalizar.Enabled = value;
            this.txtNomePacote.Enabled = value;
            this.btnLimpar.Enabled = value;
            this.cmbProdutos.Enabled = value;
        }

        private void ValidateField(Control txtField, string message)
        {
            if (txtField.Text == "")
            {
                errorProviderPackager.SetError(txtField, message);
                _formIsValid = false;
            }
            else
                errorProviderPackager.SetError(txtField, "");
        }

        private void Execute(string productName, string uriBranch, string uriSetup, string module, string version, string localPath, string packageTitle, List<string> descriptions)
        {
            ConfigScreen(false);

            ExecuteTasks tasks = new ExecuteTasks();
            tasks.MessageReceived += new EventHandler<Deployment.BuildManager.ExternalProcess.Common.MessageEventArgs>(tasks_MessageReceived);
            try
            {
                tasks.Execute(productName, uriBranch, uriSetup, module, version, localPath, packageTitle, descriptions);
                MessageBox.Show("Empacotamento Gerado com Sucesso.");
            }
            catch (ThreadAbortException abortException)
            {
                MessageBox.Show((string)abortException.ExceptionState);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                ConfigScreen(true);
                btnCancelar.Visible = false;

                lblResultado.Text = "";
                lblResultado.Update();

                StopProgressBar();
            }
        }

        private void StartProgressBar()
        {
            prgProgresso.Style = ProgressBarStyle.Marquee;
            prgProgresso.MarqueeAnimationSpeed = 40;
            prgProgresso.Update();
        }

        private void StopProgressBar()
        {
            prgProgresso.Style = ProgressBarStyle.Blocks;
            prgProgresso.MarqueeAnimationSpeed = 0;
            prgProgresso.Update();
        }

        public void tasks_MessageReceived(object sender, Deployment.BuildManager.ExternalProcess.Common.MessageEventArgs e)
        {
            if (this.lblResultado.InvokeRequired)
            {
                SetMessageReceivedCallback d = new SetMessageReceivedCallback(tasks_MessageReceived);
                this.Invoke(d, new object[] { sender, e });
            }
            else
            {
                this.lblResultado.Text = e.Message;
                this.lblResultado.Update();
                Thread.Sleep(100);
            }
        }        

        #endregion
    }
}
